package controller

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/bcrypt"
	"jiaqin/common"
	"jiaqin/dto"
	"jiaqin/model"
	"jiaqin/response"
	"jiaqin/utils"
	"log"
	"net/http"
)

func Register(ctx *gin.Context) {
	DB:=common.GetDB()
	//获取参数
	telephone:=ctx.PostForm("telephone")
	name:=ctx.PostForm("name")
	password:=ctx.PostForm("password")
	//c.Query 是获取 URL 路径中问号后面的变量值。例如：/api/books?limit=20
	//c.Param 是获取 URL 路径中问号前的对应值。例如：/api/books/20  /user/:name  之类
	//说白了，c.Query和c.Param是 查询请求URL后面拼接的参数
	//c.PostForm("name") 从表单中查询参数

	fmt.Println(name,password,telephone)
	//数据验证
	if len(telephone)!=11{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"手机号必须为11位")
		return
	}//HTTP 422 返回码 表示服务器理解请求实体的content type,并且请求实体的语法是正确的，但是服务器不能处理所包含的指示
	if len(password)<6{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"密码不能少于6位")
		return
	}
	if len(name)==0{
		name = utils.RandomString(10)
	}
	//判断手机号是否存在
	log.Println(name,telephone,password)
	if isTelephoneExist(DB,telephone){
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"用户已存在")
		return
	}
	//创建用户
	//先是进行密码加密，在数据库中会加密显示
	hashPassword,err:=bcrypt.GenerateFromPassword([]byte(password),bcrypt.DefaultCost)
	if err!=nil {
		response.Response(ctx,http.StatusUnprocessableEntity,500,nil,"加密错误")
	} // 500为服务器内部错误
	newuser := model.User{
		Name: name,
		Password: string(hashPassword),
		Telephone: telephone,
	}
	DB.Create(&newuser)
	response.Success(ctx,nil,"注册成功")
}

func Login(ctx *gin.Context)  {
	//获取参数
	DB:=common.GetDB()
	password:=ctx.PostForm("password")
	telephone:=ctx.PostForm("telephone")

	//数据验证
	if len(telephone)!=11{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"手机号不足11位")
		return
	}
	if len(password)<6{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"密码不能少于6位")
		return
	}

	//判断手机号
	var user model.User
	DB.Where("telephone=?",telephone).First(&user) //别忘了要加取地址符
	if user.ID==0{
		response.Response(ctx,http.StatusUnprocessableEntity,422,nil,"用户不存在")
		return
	}

	//判断密码
	if err:=bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password) ); err!=nil {
		response.Fail(ctx,nil,"密码错误")
		return
	} //第一个参数是原始的加密后的密码，第二个参数是要对比的密码

	//发放token
	token,err:=common.ReleaseToken(user)

	if err!=nil{
		response.Response(ctx,http.StatusInternalServerError,500,nil,"系统异常")
		log.Printf("token generate error: %v",err)
	}

	//返回结果
	response.Success(ctx,gin.H{"token":token},"登录成功")
}

func isTelephoneExist(db *gorm.DB,telephone string)bool  {
	var user model.User
	db.Where("telephone = ?",telephone).First(&user)
	if user.ID!=0{
		return true
	}
	return false
}

func Info(ctx *gin.Context)  {
	user,_:= ctx.Get("user") //从上下文中获取用户信息
	response.Success(ctx,gin.H{"user":dto.ToUserdto(user.(model.User))},"")
	// 类型断言 element.(T) element相当于一个interface{} 检查user的动态类型是否是 model.User
}